package com.tbit.uqbike.service.business.impl;

import com.tbit.uqbike.annos.EncapsulateMap;
import com.tbit.uqbike.enums.SystemCodeEnum;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.pojo.MemberFee;
import com.tbit.uqbike.object.pojo.MoneyData;
import com.tbit.uqbike.object.pojo.StatPark;
import com.tbit.uqbike.object.pojo.UserMember;
import com.tbit.uqbike.object.value.UserRcDetail;
import com.tbit.uqbike.service.business.MemberFeeService;
import com.tbit.uqbike.webmanager.dao.core.MemberFeeDao;
import com.tbit.uqbike.webmanager.dao.stat.DepositOrderDayStaDao;
import com.tbit.uqbike.webmanager.util.StringUtil;
import com.tbit.utils.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author chenmengran
 * @Description: 会员费用
 * @date 2019\7\12 001214:28
 */
@Service
public class MemberFeeServiceImpl implements MemberFeeService {
    @Autowired
    private MemberFeeDao memberFeeDao;
    @Autowired
    private DepositOrderDayStaDao depositOrderDayStaDao;

    @Override
    public void add(MemberFee memberFee) {
        memberFee.setCreatTime(new Date());
        memberFee.setUpdateTime(new Date());
        memberFeeDao.add(memberFee);
    }

    @Override
    public void update(MemberFee memberFee) {
        memberFee.setUpdateTime(new Date());
        memberFeeDao.update(memberFee);
    }

    @Override
    public List<MemberFee> find(Integer accountId, Integer rowCount, Integer pageNO) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("accountId", accountId);
        params.put("rowCount", rowCount);
        params.put("start", (pageNO - 1) * rowCount);
        return memberFeeDao.find(params);
    }

    @Override
    public void del(Integer memberFeeId, Integer accountId) {
        Map<String, Object> params = new HashMap<>();
        params.put("memberFeeId", memberFeeId);
        params.put("accountId", accountId);
        memberFeeDao.del(params);
    }

    @Override
    public Integer queryCount(Integer accountId) {
        return memberFeeDao.queryCount(accountId);
    }

    @Override
    public void edit(Integer memberFeeId, Integer accountId) {
        MemberFee memberFee = memberFeeDao.getById(memberFeeId);
        if (memberFee == null) {
            throw new BaseException(SystemCodeEnum.MEMBERFEE_NOT_EXIST);
        }
        if (!accountId.equals(memberFee.getAccountId())) {
            throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
        }
        memberFeeDao.edit(memberFeeId);
    }

    @Override
    public List<UserMember> userMemPage(Integer userId, Integer rowCount, Integer pageNO) {
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("rowCount", rowCount);
        params.put("page", (pageNO - 1) * rowCount);
        return memberFeeDao.userMemPage(params);
    }

    @Override
    public Integer userMemCount(Integer userId) {
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        return memberFeeDao.userMemCount(params);
    }

    @Override
    public Integer getMoneyByTime(List<Integer> accountIds, String startTime, String endTime, Integer type) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountIds", StringUtil.getListString(accountIds));
        params.put("startTime", startTime);
        params.put("endTime", endTime);
        params.put("type", type);
        return memberFeeDao.getMoneyByTime(params);
    }

    @Override
    public List<StatPark> statByType(List<Integer> accountIds, String startTime, String endTime,
                                     Integer type) {
        Date now = new Date();
        long nowTime = now.getTime();
        String ymd = DateTimeUtil.formatDateYMD(now);
        String time = ymd + " 00:00:00";
        long morningStartTime = DateTimeUtil.StringToDateTime(time).getTime();
        time = ymd + " 03:00:00";
        long nightStartTime = DateTimeUtil.StringToDateTime(time).getTime();
        List<StatPark> statParks = new ArrayList<>();
        Map<String, Object> params = new HashMap<>();
        params.put("accountIds", StringUtil.getListString(accountIds));
        params.put("endTime", endTime);
        params.put("type", type);
        params.put("startTime", startTime);
        Map<String, StatPark> stat = new HashMap<>();
        List<String> daysStr = DateTimeUtil.findDaysStr(DateTimeUtil.formatDateYMD(DateTimeUtil.StringToDateTime(startTime)), DateTimeUtil.formatDateYMD(DateTimeUtil.StringToDateTime(endTime)));
        if (type == 0) {
            List<StatPark> statParks1 = depositOrderDayStaDao.statByType(params);
            for (StatPark statPark : statParks1) {
                stat.put(statPark.getName(), statPark);
            }
            daysStr.forEach(day -> {
                Date start = DateTimeUtil.getYesterdayHHMMSS(day, -1);
                Date end = DateTimeUtil.getYesterdayHHMMSS(day, 0);
                params.put("startTime", DateTimeUtil.DateTimeToString(start));
                params.put("endTime", DateTimeUtil.DateTimeToString(end));
                if (DateTimeUtil.formatDateYMD(end).equals(DateTimeUtil.getNowTimeYMD())) {
                    statParks.add(memberFeeDao.statByType(params).get(0));
                } else if (nowTime >= morningStartTime && nowTime < nightStartTime && day.equals(DateTimeUtil.getYesterday())) {
                    /**兼容0-3点前一日订单未统计*/
                    statParks.add(memberFeeDao.statByType(params).get(0));
                } else {
                    if (stat.containsKey(day)) {
                        statParks.add(stat.get(day));
                    } else {
                        statParks.add(new StatPark(0, 0, day));
                    }
                }
            });
            return statParks;
        }
        return memberFeeDao.statByType(params);
    }

    @Override
    public List<UserRcDetail> getMemPage(Integer accountId, Integer type, Long startTime,
                                         Long endTime, Integer pageNO, Integer rowCount) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        if (startTime != null) {
            params.put("startTime", new Date(startTime));
        }
        if (endTime != null) {
            params.put("endTime", new Date(endTime));
        }
        params.put("type", type);
        params.put("page", (pageNO - 1) * rowCount);
        params.put("rowCount", rowCount);
        return memberFeeDao.getMemPage(params);
    }

    @Override
    public Integer getMemCount(Integer accountId, Integer type, Long startTime, Long endTime) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        if (startTime != null) {
            params.put("startTime", new Date(startTime));
        }
        if (endTime != null) {
            params.put("endTime", new Date(endTime));
        }
        params.put("type", type);
        return memberFeeDao.getMemCount(params);
    }

    @Override
    public List<UserRcDetail> export(Integer accountId, Integer type, Long startTime,
                                     Long endTime) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        if (startTime != null) {
            params.put("startTime", new Date(startTime));
        }
        if (endTime != null) {
            params.put("endTime", new Date(endTime));
        }
        params.put("memberFeeType", type);
        return memberFeeDao.export(params);
    }

    @Override
    public MoneyData getTotalMoney(Integer accountId, Integer type, Long startTime, Long endTime) {
        Map<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        if (startTime != null) {
            params.put("startTime", new Date(startTime));
        }
        if (endTime != null) {
            params.put("endTime", new Date(endTime));
        }
        params.put("type", type);
        return memberFeeDao.getTotalMoney(params);
    }

    @Override
    @EncapsulateMap
    public List<Map<String, Object>> memCountByType(HashMap<Object, Object> params, Integer accountId, Integer type, Long startTime, Long endTime) {
        return memberFeeDao.selectMemCountByType(params);
    }

    @Override
    public UserMember userVipPageByAccountIdList(Integer userId, List<Integer> accountIdList) {
        return memberFeeDao.userVipPageByAccountIdList(userId, accountIdList);
    }
}
